package com.wahoyu.exportwordtest.service;

import cn.hutool.core.lang.UUID;
import com.wahoyu.exportwordtest.domain.R;
import com.wahoyu.exportwordtest.api.RemoteFileService;
import com.wahoyu.exportwordtest.domain.SaRunReport;
import com.wahoyu.exportwordtest.domain.SysFile;
import com.wahoyu.exportwordtest.mapper.SaRunReportMapper;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Minio文件上传服务
 * @Author wanghongyu02
 * @Date 2025/5/7 15:01
 */
@Service
@Slf4j
public class MinioService {

    @Autowired
    SaRunReportMapper saRunReportMapper;

    @Autowired
    RemoteFileService fileService;

    @Autowired
    private RemoteFileService remoteFileService;

    // word文件夹路径
    @Value("${wordPath:/pathError}")
    private String wordPath;

    private String MODEL_FILE_PATH;

    @PostConstruct
    public void initPaths() {
        this.MODEL_FILE_PATH = wordPath + "word/doc/tmp.docx";
    }

    public void uploadFileToMinio(String fileName, File outputFile) {

        // 初始化任务信息
        String uuid = UUID.fastUUID().toString(true);
        SaRunReport runReportLog = new SaRunReport();
        runReportLog.setId(uuid);
        runReportLog.setReportName(fileName);
        runReportLog.setStatus(0);
        runReportLog.setFileType("运行报告");
        saRunReportMapper.insertLog(runReportLog);

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(10); // 设置核心线程数
        taskExecutor.setMaxPoolSize(20);  // 设置最大线程数
        taskExecutor.setQueueCapacity(50); // 设置队列容量
        taskExecutor.setThreadNamePrefix("MinioUploadThread-"); // 设置线程名前缀
        taskExecutor.initialize();
        // 异步将文件上传到Minio
        taskExecutor.execute(() -> {
            // 将文件上传（同步）到minio
            log.info("{} 同步文件开始", fileName);
            String syncFileUrl;
            try {
                syncFileUrl = this.syncFile(outputFile);
            } catch (Exception e) {
                log.error("{} 同步文件失败", fileName, e);
                runReportLog.setStatus(2);
                runReportLog.setStatusDesc("同步文件" + fileName + "失败..." + e.getMessage());
                saRunReportMapper.updateById(runReportLog);

                // 删除临时本地文件
                this.deleteLocalFile(outputFile);
                return;
            }

            log.info("{} 同步文件成功",fileName);
            runReportLog.setStatus(1);
            runReportLog.setFileUrl(handleFileName(syncFileUrl));
            saRunReportMapper.updateById(runReportLog);

            // 删除临时本地文件
            deleteLocalFile(outputFile);
            log.info("{} 数据写入完成",fileName);
        });
    }

    /**
     * 同步文件
     * @param f
     * @return
     */
    private String syncFile(File f) {
        R<SysFile> upload = fileService.upload(f);
        int code = upload.getCode();
        if (code == 200) {
            return upload.getData().getUrl();
        } else {
            throw new RuntimeException("同步文件失败" + upload.getMsg());
        }
    }

    //配置是否需要删除
    private boolean deleteLocalFile(File f) {
        log.info("删除临时文件{}", f.getName());
        return f.delete();
    }

    /**
     * 绝对路径提取为相对路径
     * @param file
     * @return
     */
    private String handleFileName(String file){
        //以http开头的，去除路径中的endpoint和bucketname
        if (file.startsWith("http")) {
            file = file.replaceFirst("//","");
            String[] fUrlArray = file.split("/");
            StringBuilder finV = new StringBuilder();
            //i =0 未 endpoint   ; i=1 为bucketname
            for (int i = 2; i < fUrlArray.length; i++) {
                if (i > 2) finV.append("/");
                finV.append(fUrlArray[i]);
            }
            return finV.toString();
        } else if (file.startsWith("/")) {
            return file.replaceFirst("/", "");
        }

        return file;
    }


    /**
     * 下载模板文件
     * @param remotePath
     * @return
     * @author wanghongyu02
     * @Date 2025/5/9 13:29
     * @throws IOException
     */
    public File downloadFile(String remotePath) throws IOException {

        // 调用Feign客户端
        Response response = remoteFileService.downloadFileLocal(remotePath);

        // 验证响应状态
        if (response.status() != HttpStatus.OK.value()) {
            throw new IOException("文件下载失败，状态码：" + response.status());
        }

        // 创建目标文件路径
        Path outputPath = Paths.get(MODEL_FILE_PATH);
        Files.createDirectories(outputPath.getParent());

        // 流式写入文件
        try (InputStream is = response.body().asInputStream();
             OutputStream os = new FileOutputStream(outputPath.toFile())) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        }

        return outputPath.toFile();
    }
}
